package com.sz.mes.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.core.util.BeanUtils;
import com.diboot.core.util.S;
import com.diboot.core.vo.JsonResult;
import com.diboot.iam.entity.IamUser;
import com.diboot.iam.mapper.IamUserMapper;
import com.diboot.iam.util.IamSecurityUtils;
import com.sz.mes.dto.ClockInDTO;
import com.sz.mes.dto.ReworkClockInDTO;
import com.sz.mes.entity.*;
import com.sz.mes.mapper.*;
import com.sz.mes.service.ReworkClockInService;
import com.sz.mes.service.impl.BaseCustomServiceImpl;
import com.sz.mes.vo.ClockInDetailVO;
import com.sz.mes.vo.GenerateTechniqueVO;
import com.sz.mes.vo.TechniqueDetailVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
* 返工上下机记录相关Service实现
* @author hem
* @version 1.0
* @date 2024-10-26
 * Copyright © szhs
*/
@Service
@Slf4j
public class ReworkClockInServiceImpl extends BaseCustomServiceImpl<ReworkClockInMapper, ReworkClockIn> implements ReworkClockInService {
    @Autowired
    private TechniqueMapper techniqueMapper;
    @Autowired
    private ClockInMapper clockInMapper;
    @Autowired
    private ReworkTechniqueMapper reworkTechniqueMapper;
    @Autowired
    private TechMapper techMapper;
    @Autowired
    private ReworkClockInMapper reworkClockInMapper;
    @Autowired
    private IamUserMapper iamUserMapper;
    @Autowired
    private ProductTaskMapper productTaskMapper;
    @Autowired
    private OutputMapper outputMapper;
    @Autowired
    private CompleteRptMapper completeRptMapper;

    @Override
    public JsonResult generateTechnique(GenerateTechniqueVO generateTechniqueVO) throws ParseException {
        if (generateTechniqueVO.getTaskNum().equals("") && generateTechniqueVO.getTechName().equals("") && generateTechniqueVO.getEquipmentNumber().equals("")) {
            return JsonResult.FAIL_OPERATION("漏扫描，请重新扫描");
        }
        Long currentUserId = IamSecurityUtils.getCurrentUserId();
        IamUser iamUser = iamUserMapper.selectById(currentUserId);

        String workEquipment = generateTechniqueVO.getWorkEquipment();

        QueryWrapper<Tech> tqw = new QueryWrapper<>();
        tqw.eq("task_num", generateTechniqueVO.getTaskNum());
        tqw.eq("tech_name", generateTechniqueVO.getTechName());
        tqw.eq("id", generateTechniqueVO.getId());
        Tech tech = techMapper.selectOne(tqw);
        if (tech == null) {
            return JsonResult.FAIL_OPERATION("该任务单不存在此工艺");
        }

        //判断是否为返工工单
        QueryWrapper<Tech> techQueryWrapper = new QueryWrapper<>();
        techQueryWrapper.eq("task_num", generateTechniqueVO.getTaskNum());
        List<Tech> techList = techMapper.selectList(techQueryWrapper);

        QueryWrapper<Technique> tQueryWrapper = new QueryWrapper<>();
        tQueryWrapper.eq("task_num", generateTechniqueVO.getTaskNum());
        tQueryWrapper.eq("tech_name", techList.get(techList.size() - 1).getTechName());
        List<Technique> techniqueList = techniqueMapper.selectList(tQueryWrapper);
        Long sum = 0L;
        if ( techniqueList.size() != 0 ){
//            List<Long> idList = techniqueList.stream().map(Technique::getId).collect(Collectors.toList());
//            QueryWrapper<Output> oQueryWrapper = new QueryWrapper<Output>()
//                    .in("tech_id",idList);
//            List<Output> outputs = outputMapper.selectList(oQueryWrapper);

//            if ( outputs.size() != 0 ){
                Long good = techniqueList.stream().mapToLong(Technique::getGoodQuantity).sum();
                Long bad = techniqueList.stream().mapToLong(Technique::getBadQuantity).sum();
                sum=sum+good+bad;
//            }
        }
        if ( sum != 0 ) {

//            QueryWrapper<ReworkTechnique> queryWrapper = new QueryWrapper<>();
//            queryWrapper.eq("task_num", generateTechniqueVO.getTaskNum());
//            queryWrapper.eq("tech_name", generateTechniqueVO.getTechName());
//            queryWrapper.eq("work_equipment", generateTechniqueVO.getWorkEquipment());
//            ReworkTechnique techniqueO = reworkTechniqueMapper.selectOne(queryWrapper);
            //返工
//            if (techniqueO == null) {
            ReworkTechnique newTechnique = new ReworkTechnique();
            newTechnique.setUserName(iamUser.getRealname());
            newTechnique.setTechId(tech.getId());
            newTechnique.setTechName(tech.getTechName());
            newTechnique.setTaskNum(tech.getTaskNum());
            newTechnique.setTechTime(tech.getTechTime());
            newTechnique.setEquipment(tech.getEquipment());
            newTechnique.setWorkEquipment(workEquipment);
            newTechnique.setIsUsed(1);
            newTechnique.setState(2);
            newTechnique.setStartTime(new Date());
            newTechnique.setIsChangeWork(generateTechniqueVO.getIsChangeWork());
            newTechnique.setOutput(0L);

            newTechnique.setIsRework(1);
            int insert = reworkTechniqueMapper.insert(newTechnique);

            Long techniqueId = newTechnique.getId();
            //生成加工任务后上机
            ReworkClockIn clockIn = new ReworkClockIn();
            clockIn.setTaskNum(generateTechniqueVO.getTaskNum());
            clockIn.setEquipmentNumber(generateTechniqueVO.getWorkEquipment());
            clockIn.setTechName(generateTechniqueVO.getTechName());
            clockIn.setOperated(1);
            clockIn.setOutput(0);
            //交班状态
            clockIn.setIsChangeWork(generateTechniqueVO.getIsChangeWork());

            clockIn.setTechniqueId(techniqueId);
            clockIn.setUserId(currentUserId);
            clockIn.setUserName(iamUser.getRealname());
            clockIn.setPid(0L);
            clockIn.setUserId(iamUser.getId());
            clockIn.setUserName(iamUser.getRealname());
            clockIn.setOutput(0);
            clockIn.setIsChangeWork(clockIn.getIsChangeWork());
            boolean entity = super.createEntity(clockIn);

            if (insert == 1 && entity) {
                return JsonResult.OK("生成工序任务成功");
            } else {
                return JsonResult.FAIL_EXCEPTION("生成失败");
            }

            } else {
                return JsonResult.FAIL_EXCEPTION("当前任务单质检无产出，不能创建返修工序");
            }

    }

    @Override
    public JsonResult upplane(ReworkClockIn reworkClockIn){
        QueryWrapper<ReworkTechnique> tqw = new QueryWrapper<>();
        tqw.eq("task_num", reworkClockIn.getTaskNum());
        tqw.eq("tech_name", reworkClockIn.getTechName());
        tqw.eq("work_equipment", reworkClockIn.getEquipmentNumber());
//        tqw.eq("tech_id", clockIn.getTechniqueId());
        ReworkTechnique technique = reworkTechniqueMapper.selectOne(tqw);


        IamUser iamUser = iamUserMapper.selectById(IamSecurityUtils.getCurrentUserId());

        if (technique != null) {
            technique.setIsUsed(1);
//            technique.setIsChangeWork(clockIn.getIsChangeWork());
//            technique.setUserName(iamUser.getRealname());
//            technique.setStartTime(new Date());
        }
        int i = reworkTechniqueMapper.updateById(technique);

        reworkClockIn.setPid(0L);
        reworkClockIn.setUserId(iamUser.getId());
        reworkClockIn.setUserName(iamUser.getRealname());
        reworkClockIn.setOutput(0);
        reworkClockIn.setIsChangeWork(reworkClockIn.getIsChangeWork());
        boolean entity = super.createEntity(reworkClockIn);

        if ( entity && i == 1) {
            return JsonResult.OK("上机成功");
        } else {
            return JsonResult.FAIL_EXCEPTION("上机失败");
        }
    }

    @Override
    public JsonResult deplane(ReworkClockInDTO reworkClockInDTO) {
        ReworkTechnique technique = reworkTechniqueMapper.selectById(reworkClockInDTO.getTechniqueId());
        IamUser iamUser = iamUserMapper.selectById(IamSecurityUtils.getCurrentUserId());

        //同步产出
        //查本人这道工序上机的操作记录
        QueryWrapper<ReworkClockIn> cqw = new QueryWrapper<ReworkClockIn>()
                .eq("technique_id",technique.getId())
                .eq("user_name",iamUser.getRealname())
                .eq("operated",1);
//                .last("ORDER BY id DESC LIMIT 1");
//        ClockIn clockIn2 = clockInMapper.selectOne(cqw);
        List<ReworkClockIn> upplane = reworkClockInMapper.selectList(cqw);

        //查本人这道工序下机的操作记录
        QueryWrapper<ReworkClockIn> dqw = new QueryWrapper<ReworkClockIn>()
                .eq("technique_id",technique.getId())
                .eq("user_name",iamUser.getRealname())
                .eq("operated",0);
        List<ReworkClockIn> deplane = reworkClockInMapper.selectList(dqw);
//        ClockIn clockIn1 = clockInMapper.selectOne(dqw);

        int ins=0;
        if ( upplane.size() > 1 ){
            //当前下机时间在协调或交班人的上机时间之后
            QueryWrapper<ReworkClockIn> eq1 = new QueryWrapper<ReworkClockIn>()
                    .eq("technique_id",reworkClockInDTO.getTechniqueId())
                    .eq("operated",1)
                    .gt("create_time",upplane.get(upplane.size()-1).getCreateTime());
            List<ReworkClockIn> clockIns = reworkClockInMapper.selectList(eq1);
            ins=clockIns.size();
        }


        //没有过这条上机记录对应的下机记录
        if ( deplane.size() == 0 && ins == 0 ) {
            if (technique != null){
                technique.setIsUsed(0);
            }
            technique.setGoodQuantity(technique.getGoodQuantity()+reworkClockInDTO.getGoodQuantity());
            technique.setBadQuantity(technique.getBadQuantity()+reworkClockInDTO.getBadQuantity());
            technique.setOutput(technique.getOutput()+reworkClockInDTO.getOutput());
            int i = reworkTechniqueMapper.updateById(technique);

            reworkClockInDTO.setPid(upplane.get(upplane.size()-1).getId());
            reworkClockInDTO.setUserId(IamSecurityUtils.getCurrentUserId());
            reworkClockInDTO.setUserName(iamUser.getRealname());
            reworkClockInDTO.setOperated(0);
            reworkClockInDTO.setIsChangeWork(reworkClockInDTO.getIsChangeWork());
            reworkClockInDTO.setTechniqueId(technique.getId());
            int insert = reworkClockInMapper.insert(reworkClockInDTO);
            if (i == 1 && insert == 1) {
                return JsonResult.OK("已下机");
            }
        }else if (ins != 0){
            return JsonResult.FAIL_OPERATION("超过固定生产时间，不能下机，请补卡");
        }else if ( deplane.size() != 0 && ins == 0 ) {
            if (technique != null) {
                technique.setIsUsed(0);
            }
            technique.setGoodQuantity(technique.getGoodQuantity()+reworkClockInDTO.getGoodQuantity());
            technique.setBadQuantity(technique.getBadQuantity()+reworkClockInDTO.getBadQuantity());
            technique.setOutput(technique.getOutput()+reworkClockInDTO.getOutput());
            int i = reworkTechniqueMapper.updateById(technique);

            reworkClockInDTO.setPid(upplane.get(upplane.size()-1).getId());
            reworkClockInDTO.setUserId(IamSecurityUtils.getCurrentUserId());
            reworkClockInDTO.setUserName(iamUser.getRealname());
            reworkClockInDTO.setOperated(0);
            reworkClockInDTO.setIsChangeWork(reworkClockInDTO.getIsChangeWork());
            reworkClockInDTO.setTechniqueId(technique.getId());
            int insert = reworkClockInMapper.insert(reworkClockInDTO);
            if (i == 1 && insert == 1) {
                return JsonResult.OK("已下机");
            }
        }
        return JsonResult.FAIL_EXCEPTION("下机失败");
    }

    @Override
    public JsonResult executeState(ReworkClockIn reworkClockIn) {
        QueryWrapper<ReworkTechnique> tqw = new QueryWrapper<>();
//        tqw.eq("id",clockIn.getTechniqueId());
//        tqw.eq("task_num", reworkClockIn.getTaskNum());
//        tqw.eq("tech_name", reworkClockIn.getTechName());
//        tqw.eq("work_equipment", reworkClockIn.getEquipmentNumber());
        ReworkTechnique technique = reworkTechniqueMapper.selectById(reworkClockIn.getTechniqueId());

        if (technique != null) {
            technique.setIsUsed(0);
            technique.setState(1);
            technique.setEndTime(new Date());
        }
        int i = reworkTechniqueMapper.updateById(technique);

        if (i != 0) {
            return JsonResult.OK("任务已完成");
        } else {
            return JsonResult.FAIL_EXCEPTION("任务无法正常完成");
        }
    }

    @Override
    public JsonResult findProductDetail(ReworkClockIn reworkClockIn) {
        QueryWrapper<ReworkClockIn> wrapper = new QueryWrapper<ReworkClockIn>()
                .eq("tech_name",reworkClockIn.getTechName())
                .eq("task_num",reworkClockIn.getTaskNum())
                .orderByDesc("create_time");
        List<ReworkClockIn> clockIns = reworkClockInMapper.selectList(wrapper);

        List<ClockInDetailVO> clockInDetailVOS = BeanUtils.convertList(clockIns, ClockInDetailVO.class);


//        QueryWrapper<ReworkTechnique> tqw = new QueryWrapper<ReworkTechnique>()
//                .eq("tech_name",reworkClockIn.getTechName())
//                .eq("task_num",reworkClockIn.getTaskNum())
//                .eq("work_equipment",reworkClockIn.getEquipmentNumber());
        ReworkTechnique technique = reworkTechniqueMapper.selectById(reworkClockIn.getTechniqueId());

        QueryWrapper<ProductTask> pqw = new QueryWrapper<>();
        pqw.eq("task_num", reworkClockIn.getTaskNum());
        List<ProductTask> productTaskList = productTaskMapper.selectList(pqw);
        ProductTask productTask = productTaskList.get(0);

        TechniqueDetailVO techniqueDetailVO = new TechniqueDetailVO();
        techniqueDetailVO.setTaskNum(reworkClockIn.getTaskNum());
        techniqueDetailVO.setTaskName(productTask.getProductName());
        techniqueDetailVO.setQuantity(productTask.getQuantity());
        techniqueDetailVO.setClockInList(clockInDetailVOS);
        techniqueDetailVO.setTechName(reworkClockIn.getTechName());
        techniqueDetailVO.setEquipment(technique.getWorkEquipment());
        techniqueDetailVO.setOutput(technique.getOutput());
        techniqueDetailVO.setIsRework(technique.getIsRework());
        return JsonResult.OK(techniqueDetailVO);
    }

    @Override
    public JsonResult findTaskList(Integer state) {
        ArrayList<ReworkTechnique> list = new ArrayList<>();
        QueryWrapper<ReworkClockIn> eq = new QueryWrapper<ReworkClockIn>()
                .eq("user_id", IamSecurityUtils.getCurrentUserId());

        List<ReworkClockIn> clockInList = reworkClockInMapper.selectList(eq);
//        List<String> clockInList = clockInMapper.selectTaskNum(technique.getUserId());
        List<Long> list1 = new ArrayList<>();
        for (ReworkClockIn clockIn:clockInList){
            if (!list1.contains(clockIn.getTechniqueId())){
                list1.add(clockIn.getTechniqueId());
            }
        }
        for (Long techniqueId:list1){
            QueryWrapper<ReworkTechnique> qw = new QueryWrapper<ReworkTechnique>()
                    .eq("id",techniqueId)
                    .eq("state",state)
                    .orderByDesc("create_time");
            List<ReworkTechnique> techniqueList = reworkTechniqueMapper.selectList(qw);

            if (techniqueList!=null && techniqueList.size()!=0){
                for (ReworkTechnique technique:techniqueList){
                    list.add(technique);
                }
            }
        }
        return JsonResult.OK(list);
    }

    @Override
    public JsonResult getTaskInfo(Equipment equipment) {
        QueryWrapper<ReworkTechnique> reqw = new QueryWrapper<ReworkTechnique>()
                .eq("work_equipment", equipment.getEquipmentName());
        List<ReworkTechnique> reworkTechniqueList = reworkTechniqueMapper.selectList(reqw);

        List<String> taskNumList = reworkTechniqueList.stream().map(ReworkTechnique::getTaskNum).collect(Collectors.toList());

        for (String taskNum : taskNumList){
            QueryWrapper<Tech> tqw = new QueryWrapper<>();
//        tqw.eq("equipment",equipment.getEquipmentName());
            tqw.in("tech_name",equipment.getEquipmentType());
            List<Tech> techList = techMapper.selectList(tqw);
            Tech techName = techList.get(techList.size() - 1);
        }

        QueryWrapper<ProductTask> pqw = new QueryWrapper<>();
        pqw.in("task_num",taskNumList);
        List<ProductTask> taskList = productTaskMapper.selectList(pqw);
        if (taskList == null || taskList.size() == 0){
            return JsonResult.OK(new ArrayList<>());
        }
        Map<String, List<ProductTask>> map = taskList.stream().filter(productTask -> {
            String receiptNum = productTask.getReceiptNum();
            String substring = receiptNum.substring(2);
            String completeRptReceiptNum = "WG" + substring;
            QueryWrapper<CompleteRpt> completeRptQueryWrapper = new QueryWrapper<>();
            completeRptQueryWrapper.eq("receipt_num", completeRptReceiptNum);
            List<CompleteRpt> completeRpts = completeRptMapper.selectList(completeRptQueryWrapper);
            // 只要生产完工表有数据的时候，任务才算已完成
            return completeRpts.size()  == 0;
        }).collect(Collectors.groupingBy(ProductTask::getReceiptNum));
        List<ProductTask> collect = map.values().stream().map(productTasks -> productTasks.get(0)).collect(Collectors.toList());
        return JsonResult.OK(collect);
    }

}
